package jvlite.authority;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jvlite.exception.AuthException;
import jvlite.ioc.BeanFactory;
import jvlite.util.StrUtil;

public class DefaultAuthManager extends AbstractAuthManager {

	@SuppressWarnings("unchecked")
	public Boolean checkClzAuth(Object target, List<String> hasAuthList){
		
		Boolean isAuth = false;
		Map<String, Object> needAuthMap = (Map<String, Object>) BeanFactory.getAuthMap().get(target.getClass().getName());
		if (null != needAuthMap) {
			String[] needClzAuthList = (String[]) needAuthMap.get("ClzAuth");//only the most high authentic
			if (null != needClzAuthList && null != hasAuthList) {
				if (authWayName.equals("all")) {
					if (hasAuthList.containsAll(Arrays.asList(needClzAuthList))) {
						isAuth = true;
					}
				} else if (authWayName.equals("any")) {
					for (String needClzAuth : needClzAuthList) {
						if (hasAuthList.contains(needClzAuth)) {
							isAuth = true;
						}
					}
				}
			} else {
				isAuth = true;
			}
		} else {
			isAuth = true;
		}
		return isAuth;
		
	}

	@SuppressWarnings("unchecked")
	public Boolean checkMtdAuth(Object target, Method method, List<String> hasAuthList){
		
		Boolean isAuth = false;
		Map<String, Object> needAuthMap = (Map<String, Object>) BeanFactory.getAuthMap().get(target.getClass().getName());
//		if (null != needAuthMap) {
		if (StrUtil.objNotEmpty(needAuthMap)) {
			Map<String, Object> needMtdAuthMap = (Map<String, Object>) needAuthMap.get("MtdAuth");	
			
			String mtdName = method.getName();
			if (needMtdAuthMap.keySet().contains(mtdName)) {
				String[] needMtdAuthList = (String[]) needMtdAuthMap.get(mtdName);//only the most high authentic
//				System.out.println(mtdName+" needMtdAuthList:"+Arrays.toString(needMtdAuthList));
				if (null != needMtdAuthList && null != hasAuthList) {
//				if (StrUtil.objNotEmpty(needMtdAuthList)) {
					if (authWayName.equals("all")) {
						if (hasAuthList.containsAll(Arrays
								.asList(needMtdAuthList))) {
							isAuth = true;
						}
					} else if (authWayName.equals("any")) {
						for (String needMtdAuth : needMtdAuthList) {
							if (hasAuthList.contains(needMtdAuth)) {
								isAuth = true;
							}
						}
					}
				} else {
					isAuth = true;
				}
			}
		} else {
			isAuth = true;
		}
		return isAuth;
	}

	public void noAuth(HttpServletRequest request, HttpServletResponse response){
		try {
			request.getRequestDispatcher(errPagePath).forward(request, response);
		} catch (ServletException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public Boolean isGuest() {
		Boolean isGuest = false;
//		if (null == authDataSource.getHasAuthDS()) {
		if (!StrUtil.objNotEmpty(authDataSource.getHasAuthDS())){
			isGuest = true;
		}
		return isGuest;
	}
	
	public void checkAuths(Object target, Method method) throws AuthException {
/*		if (!StrUtil.objNotEmpty(authDataSource)) {
			authDataSource = JLiteContext.authManager.getAuthDataSource();
		}*/
//		AbstractAuthManager authManager = JLiteContext.authManager;
//		authDataSource = authManager.getAuthDataSource();
		if (!StrUtil.objNotEmpty(authDataSource.getHasAuthDS())) {
			authDataSource.setHasAuthDS(new ArrayList<String>());
		}
		List<String> hasAuthList = authDataSource.getHasAuthDS();
//		Boolean isGuest = this.isGuest();
//		if (this.isGuest()) {
//			throw new AuthException("no any authority");
//		}
		Boolean isClzAuth = this.checkClzAuth(target, hasAuthList);
		Boolean isMtdAuth = this.checkMtdAuth(target, method,
				hasAuthList);
		if (!isClzAuth) {
			throw new AuthException("no class auth");
		} else if (!isMtdAuth) {
			throw new AuthException("no method auth");
		}
	}
	
}
